home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / util / boot / hdenv13.lha / HDEnv / HDEnv.c < prev    next >
C/C++ Source or Header  |  1995-10-03  |  10KB  |  337 lines

  1. /****************************************************************************\
  2.  
  3. HDEnv 1.3 (3.10.95)
  4. Copyright (C) 1995 by Michael Fedrowitz <mfedrowi@ix.urz.uni-heidelberg.de>
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. \****************************************************************************/
  21.  
  22.  
  23. #include <exec/types.h>
  24. #include <exec/memory.h>
  25. #include <dos/dos.h>
  26. #include <proto/dos.h>
  27. #include <proto/exec.h>
  28. #include <stdlib.h>
  29. #include <strings.h>
  30. #include <dos.h>
  31.  
  32.  
  33. #ifndef V39
  34. void * __asm AsmCreatePool(register __d0 ULONG,register __d1 ULONG,register __d2 ULONG,register __a6 struct ExecBase *);
  35. void __asm AsmDeletePool(register __a0 void *,register __a6 struct ExecBase *);
  36. void * __asm AsmAllocPooled(register __a0 void *,register __d0 ULONG,register __a6 struct ExecBase *);
  37. void __asm AsmFreePooled(register __a0 void *,register __a1 void *,register __d0 ULONG,register __a6 struct ExecBase *);
  38.  
  39. #define CreatePool(memFlags,puddleSize,threshSize) AsmCreatePool(memFlags,puddleSize,threshSize,SysBase)
  40. #define DeletePool(poolHeader) AsmDeletePool(poolHeader,SysBase)
  41. #define AllocPooled(poolHeader,memSize) AsmAllocPooled(poolHeader,memSize,SysBase)
  42. #define FreePooled(poolHeader,memory,memSize) AsmFreePooled(poolHeader,memory,memSize,SysBase)
  43. #endif
  44.  
  45. #define VERSIONTAG "$VER: HDEnv 1.3 " __AMIGADATE__
  46.  
  47. #define ERR_BREAK 10001
  48.  
  49. #define COPYBUF 2048
  50.  
  51.  
  52. struct File {
  53.  
  54.     struct File *next,*prev;
  55.     struct FileInfoBlock fib;
  56.     char path[1];
  57. };
  58.  
  59. struct Dir {
  60.  
  61.     struct File *first,*last;
  62. };
  63.  
  64. struct HDEnv {
  65.  
  66.     void *pool;
  67.     struct Dir env,envarc;
  68.     char path[256];
  69.     char copybuf[COPYBUF];
  70.     long test,verbose;
  71. };
  72.  
  73.  
  74. #ifdef V39
  75. const long __oslibversion = 39;
  76. #else
  77. const long __oslibversion = 37;
  78. #endif
  79.  
  80. const char *versiontag = VERSIONTAG;
  81.  
  82. struct HDEnv *hde;
  83.  
  84. long error_code = 0;
  85.  
  86.  
  87. void __regargs _CXBRK(void) {
  88.  
  89.     error_code = ERR_BREAK;
  90. }
  91.  
  92.  
  93. void free_all(struct HDEnv *hde) {
  94.  
  95.     DeletePool(hde->pool);
  96.     FreeMem(hde,sizeof(struct HDEnv));
  97. }
  98.  
  99. struct HDEnv *alloc_all(void) {
  100.  
  101.     struct HDEnv *hde;
  102.  
  103.     if(hde = AllocMem(sizeof(struct HDEnv),MEMF_CLEAR)) {
  104.         if(!(hde->pool = CreatePool(MEMF_CLEAR,10000,10000))) {
  105.             error_code = ERROR_NO_FREE_STORE;
  106.             free_all(hde);
  107.         }
  108.     }
  109.     else error_code = ERROR_NO_FREE_STORE;
  110.  
  111.     return error_code ? NULL : hde;
  112. }
  113.  
  114.  
  115. void add_file(struct Dir *dir,char *path,struct FileInfoBlock *fib) {
  116.  
  117.     struct File *file;
  118.  
  119.     if(file = AllocPooled(hde->pool,sizeof(struct File)+strlen(path))) {
  120.         memcpy(&file->fib,fib,sizeof(struct FileInfoBlock));
  121.         strcpy(file->path,path);
  122.         if(dir->first) {
  123.             dir->last->next = file;
  124.             file->prev = dir->last;
  125.         }
  126.         else dir->first = file;
  127.         dir->last = file;
  128.     }
  129.     else error_code = ERROR_NO_FREE_STORE;
  130. }
  131.  
  132. void scan_dir(struct Dir *dir,char *name) {
  133.  
  134.     BOOL rc;
  135.     BPTR l;
  136.     long err;
  137.     char *path;
  138.     struct FileInfoBlock *fib;
  139.  
  140.     if(fib = AllocDosObject(DOS_FIB,NULL)) {
  141.         if(path = AllocPooled(hde->pool,256)) {
  142.             if(l = Lock(name,ACCESS_READ)) {
  143.                 rc = Examine(l,fib);
  144.                 if(rc) rc = ExNext(l,fib);
  145.                 while(rc) {
  146.                     strmfp(path,name,fib->fib_FileName);
  147.                     add_file(dir,path,fib);
  148.                     if(fib->fib_DirEntryType > 0) scan_dir(dir,path);
  149.                     chkabort();
  150.                     if(error_code) break;
  151.                     rc = ExNext(l,fib);
  152.                 }
  153.                 if(!error_code) {
  154.                     err = IoErr();
  155.                     if(err != ERROR_NO_MORE_ENTRIES) error_code = err;
  156.                 }
  157.                 UnLock(l);
  158.             }
  159.             FreePooled(hde->pool,path,256);
  160.         }
  161.         else error_code = ERROR_NO_FREE_STORE;
  162.         FreeDosObject(DOS_FIB,fib);
  163.     }
  164.     else error_code = ERROR_NO_FREE_STORE;
  165. }
  166.  
  167. struct File *find_file(struct Dir *dir,char *name) {
  168.  
  169.     struct File *file;
  170.     BOOL found = FALSE;
  171.  
  172.     file = dir->first;
  173.  
  174.     while(file) {
  175.         if(!(strcmp(file->path,name))) {
  176.             found = TRUE;
  177.             break;
  178.         }
  179.         file = file->next;
  180.     }
  181.  
  182.     return found ? file : NULL;
  183. }
  184.  
  185.  
  186. void del_files(void) {
  187.  
  188.     struct File *file;
  189.  
  190.     file = hde->env.last;
  191.  
  192.     while(file) {
  193.         if(!(find_file(&hde->envarc,file->path))) {
  194.             strmfp(hde->path,"ENV:",file->path);
  195.             if(hde->test) Printf("%s\n",hde->path);
  196.             else {
  197.                 if(hde->verbose) Printf("deleting %s...\n",hde->path);
  198.                 if(!(DeleteFile(hde->path))) error_code = IoErr();
  199.             }
  200.         }
  201.         chkabort();
  202.         if(error_code) break;
  203.         file = file->prev;
  204.     }
  205. }
  206.  
  207.  
  208. void copy_files(void) {
  209.  
  210.     struct File *file,*dest;
  211.     BOOL copy;
  212.     BPTR l,src_fh,dest_fh;
  213.     long size,allocsize,bufsize;
  214.     void *buf;
  215.  
  216.     file = hde->envarc.first;
  217.  
  218.     while(file) {
  219.         copy = FALSE;
  220.         strmfp(hde->path,"ENV:",file->path);
  221.         if(!(dest = find_file(&hde->env,file->path))) {
  222.             if(file->fib.fib_DirEntryType > 0) {
  223.                 if(hde->test) Printf("%s (created)\n",hde->path);
  224.                 else {
  225.                     if(hde->verbose) Printf("creating %s...\n",hde->path);
  226.                     if(!(l = CreateDir(hde->path))) {
  227.                         error_code = IoErr();
  228.                         break;
  229.                     }
  230.                     else UnLock(l);
  231.                 }
  232.             }
  233.             else copy = TRUE;
  234.         }
  235.         else if(file->fib.fib_DirEntryType < 0) {
  236.             if(CompareDates(&file->fib.fib_Date,&dest->fib.fib_Date)) copy = TRUE;
  237.         }
  238.  
  239.         if(copy) {
  240.             if(hde->test) Printf("ENVARC:%s to %s\n",file->path,hde->path);
  241.             else {
  242.                 if(hde->verbose) Printf("copying ENVARC:%s to %s...\n",file->path,hde->path);
  243.                 if(src_fh = Open(file->path,MODE_OLDFILE)) {
  244.                     if(dest_fh = Open(hde->path,MODE_NEWFILE)) {
  245.                         buf = NULL;
  246.                         size = file->fib.fib_Size;
  247.                         if(size > COPYBUF) {
  248.                             if(buf = AllocPooled(hde->pool,size)) {
  249.                                 allocsize = size;
  250.                                 bufsize = size;
  251.                             }
  252.                         }
  253.                         if(!buf) {
  254.                             buf = hde->copybuf;
  255.                             bufsize = COPYBUF;
  256.                             allocsize = 0;
  257.                         }
  258.                         while(size > 0) {
  259.                             if(size < bufsize) bufsize = size;
  260.                             if(Read(src_fh,buf,bufsize) == bufsize) Write(dest_fh,buf,bufsize);
  261.                             else {
  262.                                 error_code = IoErr();
  263.                                 break;
  264.                             }
  265.                             if(size < bufsize) bufsize = size;
  266.                             size -= bufsize;
  267.                         }
  268.                         if(allocsize) FreePooled(hde->pool,buf,allocsize);
  269.                         Close(dest_fh);
  270.                         if(error_code) DeleteFile(hde->path);
  271.                         else {
  272.                             SetFileDate(hde->path,&file->fib.fib_Date);
  273.                             SetProtection(hde->path,file->fib.fib_Protection);
  274.                             SetComment(hde->path,file->fib.fib_Comment);
  275.                         }
  276.                     }
  277.                     else error_code = IoErr();
  278.                     Close(src_fh);
  279.                 }
  280.                 else error_code = IoErr();
  281.             }
  282.         }
  283.         chkabort();
  284.         if(error_code) break;
  285.         file = file->next;
  286.     }
  287. }
  288.  
  289.  
  290. int main(void) {
  291.  
  292.     struct RDArgs *rda;
  293.     long arg[2] = { 0,0 };
  294.     BPTR env,envarc,old;
  295.  
  296.     if(hde = alloc_all()) {
  297.         if(rda = ReadArgs("TEST/S,VERBOSE/S",arg,NULL)) {
  298.             hde->test = arg[0];
  299.             hde->verbose = arg[1];
  300.             FreeArgs(rda);
  301.             if(env = Lock("ENV:",ACCESS_READ)) {
  302.                 if(envarc = Lock("ENVARC:",ACCESS_READ)) {
  303.                     old = CurrentDir(env);
  304.                     scan_dir(&hde->env,"");
  305.                     CurrentDir(envarc);
  306.                     scan_dir(&hde->envarc,"");
  307.                     if(!error_code) {
  308.                         if(hde->test) Printf("Would have deleted:\n");
  309.                         del_files();
  310.                         if(!error_code) {
  311.                             if(hde->test) Printf("Would have copied:\n");
  312.                             copy_files();
  313.                         }
  314.                     }
  315.                     CurrentDir(old);
  316.                     UnLock(envarc);
  317.                 }
  318.                 else error_code = IoErr();
  319.                 UnLock(env);
  320.             }
  321.             else error_code = IoErr();
  322.         }
  323.         else error_code = IoErr();
  324.         free_all(hde);
  325.     }
  326.  
  327.     if(error_code) {
  328.         if(error_code != ERR_BREAK) {
  329.             PrintFault(error_code,"HDEnv");
  330.             return RETURN_FAIL;
  331.         }
  332.         else PutStr("*** Break\n");
  333.     }
  334.  
  335.     return RETURN_OK;
  336. }
  337.